# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\validate_email.py
import re, smtplib, logging, socket

try:
    raw_input
except NameError:

    def raw_input(prompt=""):
        return input(prompt)


try:
    import DNS

    ServerError = DNS.ServerError
    DNS.DiscoverNameServers()
except (ImportError, AttributeError):
    DNS = None

    class ServerError(Exception):
        pass


WSP = "[ \\t]"
CRLF = "(?:\\r\\n)"
NO_WS_CTL = "\\x01-\\x08\\x0b\\x0c\\x0f-\\x1f\\x7f"
QUOTED_PAIR = "(?:\\\\.)"
FWS = "(?:(?:" + WSP + "*" + CRLF + ")?" + WSP + "+)"
CTEXT = "[" + NO_WS_CTL + "\\x21-\\x27\\x2a-\\x5b\\x5d-\\x7e]"
CCONTENT = "(?:" + CTEXT + "|" + QUOTED_PAIR + ")"
COMMENT = "\\((?:" + FWS + "?" + CCONTENT + ")*" + FWS + "?\\)"
CFWS = "(?:" + FWS + "?" + COMMENT + ")*(?:" + FWS + "?" + COMMENT + "|" + FWS + ")"
ATEXT = "[\\w!#$%&\\'\\*\\+\\-/=\\?\\^`\\{\\|\\}~]"
ATOM = CFWS + "?" + ATEXT + "+" + CFWS + "?"
DOT_ATOM_TEXT = ATEXT + "+(?:\\." + ATEXT + "+)*"
DOT_ATOM = CFWS + "?" + DOT_ATOM_TEXT + CFWS + "?"
QTEXT = "[" + NO_WS_CTL + "\\x21\\x23-\\x5b\\x5d-\\x7e]"
QCONTENT = "(?:" + QTEXT + "|" + QUOTED_PAIR + ")"
QUOTED_STRING = (
    CFWS + "?" + '"(?:' + FWS + "?" + QCONTENT + ")*" + FWS + "?" + '"' + CFWS + "?"
)
LOCAL_PART = "(?:" + DOT_ATOM + "|" + QUOTED_STRING + ")"
DTEXT = "[" + NO_WS_CTL + "\\x21-\\x5a\\x5e-\\x7e]"
DCONTENT = "(?:" + DTEXT + "|" + QUOTED_PAIR + ")"
DOMAIN_LITERAL = (
    CFWS + "?" + "\\[" + "(?:" + FWS + "?" + DCONTENT + ")*" + FWS + "?\\]" + CFWS + "?"
)
DOMAIN = "(?:" + DOT_ATOM + "|" + DOMAIN_LITERAL + ")"
ADDR_SPEC = LOCAL_PART + "@" + DOMAIN
VALID_ADDRESS_REGEXP = "^" + ADDR_SPEC + "$"
MX_DNS_CACHE = {}
MX_CHECK_CACHE = {}


def get_mx_ip(hostname):
    if hostname not in MX_DNS_CACHE:
        try:
            MX_DNS_CACHE[hostname] = DNS.mxlookup(hostname)
        except ServerError as e:
            if e.rcode == 3:
                MX_DNS_CACHE[hostname] = None
            else:
                raise

        return MX_DNS_CACHE[hostname]


def validate_email(email, check_mx=False, verify=False, debug=False, smtp_timeout=10):
    """Indicate whether the given string is a valid email address
    according to the 'addr-spec' portion of RFC 2822 (see section
    3.4.1).  Parts of the spec that are marked obsolete are *not*
    included in this test, and certain arcane constructions that
    depend on circular definitions in the spec may not pass, but in
    general this should correctly identify any email address likely
    to be in use as of 2011."""
    if debug:
        logger = logging.getLogger("validate_email")
        logger.setLevel(logging.DEBUG)
    else:
        logger = None
    try:
        if not re.match(VALID_ADDRESS_REGEXP, email) is not None:
            raise AssertionError
        check_mx |= verify
        if check_mx:
            if not DNS:
                raise Exception(
                    "For check the mx records or check if the email exists you must have installed pyDNS python package"
                )
            hostname = email[email.find("@") + 1 :]
            mx_hosts = get_mx_ip(hostname)
            if mx_hosts is None:
                return False
            for mx in mx_hosts:
                try:
                    if not verify:
                        if mx[1] in MX_CHECK_CACHE:
                            return MX_CHECK_CACHE[mx[1]]
                        smtp = smtplib.SMTP(timeout=smtp_timeout)
                        smtp.connect(mx[1])
                        MX_CHECK_CACHE[mx[1]] = True
                        if not verify:
                            try:
                                smtp.quit()
                            except smtplib.SMTPServerDisconnected:
                                pass

                            return True
                        status, _ = smtp.helo()
                        if status != 250:
                            smtp.quit()
                            if debug:
                                logger.debug("%s answer: %s - %s", mx[1], status, _)
                            continue
                        smtp.mail("")
                        status, _ = smtp.rcpt(email)
                        if status == 250:
                            smtp.quit()
                            return True
                        if debug:
                            logger.debug("%s answer: %s - %s", mx[1], status, _)
                        smtp.quit()
                except smtplib.SMTPServerDisconnected:
                    if debug:
                        logger.debug("%s disconected.", mx[1])
                except smtplib.SMTPConnectError:
                    if debug:
                        logger.debug("Unable to connect to %s.", mx[1])

            return
    except AssertionError:
        return False
    except (ServerError, socket.error) as e:
        if debug:
            logger.debug("ServerError or socket.error exception raised (%s).", e)
        return

    return True


if __name__ == "__main__":
    import time

    while True:
        email = raw_input("Enter email for validation: ")
        mx = raw_input("Validate MX record? [yN] ")
        if mx.strip().lower() == "y":
            mx = True
        else:
            mx = False
        validate = raw_input("Try to contact server for address validation? [yN] ")
        if validate.strip().lower() == "y":
            validate = True
        else:
            validate = False
        logging.basicConfig()
        result = validate_email(email, mx, validate, debug=True, smtp_timeout=1)
        if result:
            print("Valid!")
        else:
            if result is None:
                print("I'm not sure.")
            else:
                print("Invalid!")
            time.sleep(1)
